package com.cloud.observer;

import com.cloud.observer.annotation.ExceptionHandlerCommand;
import com.cloud.observer.annotation.ExecuteHandlerCommand;
import com.cloud.observer.annotation.ScheduledObserver;
import com.cloud.observer.annotation.SuccessHandlerCommand;
import com.cloud.observer.handler.IExceptionHandler;
import com.cloud.observer.handler.IExecuteHandler;
import com.cloud.observer.handler.successHandler.ISuccessHandler;
import com.cloud.observer.scheduledEnum.ErrorEnum;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * @author: create by God of SJF
 * @version: v1.0
 * @description: com.cloud.observer
 * @date:2021/1/12
 */
public class ScheduledObserverWrapper {

    @Autowired
    BaseScheduledObserver baseScheduledObserver;

    @Autowired
    ApplicationContext applicationContext;

    public ScheduledInfo build(ScheduledInfo scheduledInfo, ScheduledObserver ScheduledObserver, Scheduled Scheduled) {
        scheduledInfo.setLastBegin(new Date());
        scheduledInfo.setCorn(Scheduled.cron());

        ExecuteHandlerCommand[] errorHandlerCommands = ScheduledObserver.executeHandlerCommands();
        SuccessHandlerCommand[] successHandlerCommands = ScheduledObserver.successHandlerCommands();
        ExceptionHandlerCommand[] exceptionHandlerCommands = ScheduledObserver.exceptionHandlerCommands();
        List list = new ArrayList<IExecuteHandler>();
        if (null != errorHandlerCommands) {
            for (ExecuteHandlerCommand e : errorHandlerCommands) {
                ErrorEnum type = e.type();
                String beanName = e.name();
                String value = e.value();
                switch (type) {
                    case LOG:
                        Object o = applicationContext.getBean(beanName);
                        if(!(o instanceof IExecuteHandler)){
                            break;
                        }
                        if (o instanceof AbstractInitScheduledInfoLogHandler) {
                            ((AbstractInitScheduledInfoLogHandler) o).build(value);
                        }
                        if (o instanceof AbstractInitScheduledInfo) {
                            ((AbstractInitScheduledInfo) o).init(scheduledInfo);
                        }
                        list.add(o);
                        break;
                    case DING:
                        String token = "";
                        if (StringUtils.isNotBlank(value)) {
                            Environment environment = applicationContext.getEnvironment();
                            token = environment.getProperty(value);
                        }
                        if (StringUtils.isBlank(token)) {
                            break;
                        }
                        Object o2 = applicationContext.getBean(beanName);
                        if(!(o2 instanceof IExecuteHandler)){
                            break;
                        }
                        if (o2 instanceof AbstractInitScheduledInfo) {
                            ((AbstractInitScheduledInfo) o2).init(scheduledInfo);
                        }
                        if (o2 instanceof AbstractInitScheduledInfoDingDingHandler) {
                            ((AbstractInitScheduledInfoDingDingHandler) o2).build(token);
                        }

                        list.add(o2);
                        break;
                    default:
                        break;
                }
            }
            scheduledInfo.setExecuteHandlerList(list);
        }

        List list2 = new ArrayList<ISuccessHandler>();
        if (null != successHandlerCommands) {
            for (SuccessHandlerCommand e : successHandlerCommands) {
                ErrorEnum type = e.type();
                String beanName = e.name();
                String value = e.value();
                switch (type) {
                    case DING:
                        String token = "";
                        if (StringUtils.isNotBlank(value)) {
                            Environment environment = applicationContext.getEnvironment();
                            token = environment.getProperty(value);
                        }
                        if (StringUtils.isBlank(token)) {
                            break;
                        }
                        Object o2 = applicationContext.getBean(beanName);
                        if(!(o2 instanceof ISuccessHandler)){
                            break;
                        }
                        if (o2 instanceof AbstractInitScheduledInfo) {
                            ((AbstractInitScheduledInfo) o2).init(scheduledInfo);
                        }
                        if (o2 instanceof AbstractInitScheduledInfoDingDingHandler) {
                            ((AbstractInitScheduledInfoDingDingHandler) o2).build(token);
                        }
                        list2.add(o2);
                        break;
                    default:
                        break;
                }
            }
            scheduledInfo.setSuccessHandlerList(list2);
        }
        List<IExceptionHandler> list3 = new ArrayList<>();
        if (exceptionHandlerCommands != null) {
            for(ExceptionHandlerCommand e : exceptionHandlerCommands){
                ErrorEnum type = e.type();
                String beanName = e.name();
                String value = e.value();
                switch (type) {
                    case LOG:
                        Object o2 = applicationContext.getBean(beanName);
                        if (o2 instanceof IExceptionHandler) {
                            list3.add((IExceptionHandler) o2);
                        }
                        if (o2 instanceof AbstractInitScheduledInfoLogHandler) {
                            ((AbstractInitScheduledInfoLogHandler) o2).build(value);
                        }
                        break;
                    default:
                        break;
                }
            }
            scheduledInfo.setExceptionHandlerList(list3);
        }
        scheduledInfo.setErrorSend(ScheduledObserver.errorWarning());
        scheduledInfo.setSuccessSend(ScheduledObserver.succeedAlert());
        scheduledInfo.setException(null);
        scheduledInfo.setSuccessNum(1);
        scheduledInfo.setDelayNum(0);
        scheduledInfo.setDelayLimitTime(ScheduledObserver.delayTimeLimit());
        scheduledInfo.setDelayNumLimit(ScheduledObserver.delayNumLimit());
        scheduledInfo.setLastBegin(new Date());
        scheduledInfo.setLastEnd(new Date());
        scheduledInfo.setErrorSet(new HashSet<>());
        scheduledInfo.pool.scheduleAtFixedRate(new ScheduledObserverPool(scheduledInfo, baseScheduledObserver), 0, 1, TimeUnit.SECONDS);
        scheduledInfo.clean.scheduleAtFixedRate(new ScheduledObserverCleanPool(scheduledInfo, baseScheduledObserver), ScheduledObserver.executeCycle() * 100, 1, TimeUnit.SECONDS);
        return scheduledInfo;
    }
}
